<template>
  <view :style="{ zIndex }" class="popups-wrap">
    <view v-for="(item, index) in popupsList" :id="item.uuid" :key="item.uuid">
      <view
        :style="{
          top:
            index == 0
              ? firstTop + 'px'
              : firstTop + (index * 40 + index * distance) + 'px',
        }"
        :class="[item.animator, item.typeClass, { 'yd-top-0': !isDistance }]"
        class="yd-popup yd-flex-h-hL-vC"
      >
        <image class="yd-popup-icon" :src="item.icon"></image>
        <view class="yd-popup-text">{{ item.message }}</view>
        <image
          v-if="item.isClickShow"
          @tap="closeEvent(item.uuid)"
          class="yd-popup-icon"
          :src="item.closeIcon"
        ></image>
      </view>
    </view>
  </view>
</template>

<script>
export default {
  props: {
    isDistance: {
      type: Boolean,
      default: true
    },
    zIndex: {
      type: Number,
      default: 5000
    },
    firstTop: {
      type: Number,
      default: 10
    }
  },
  data() {
    return {
      popupsList: [],
      distance: 20
    }
  },
  methods: {
    // 初始化样式
    initEvent(popupItem) {
      if (popupItem.type == "info") {
        popupItem.icon = require("./images/info.png")
        popupItem.closeIcon = require("./images/infoCloseIcon.png")
        popupItem.typeClass = "yd-popup-info"
      }
      if (popupItem.type == "success") {
        popupItem.icon = require("./images/success.png")
        popupItem.closeIcon = require("./images/successCloseIcon.png")
        popupItem.typeClass = "yd-popup-success"
      }
      if (popupItem.type == "warn") {
        popupItem.icon = require("./images/warn.png")
        popupItem.closeIcon = require("./images/warnCloseIcon.png")
        popupItem.typeClass = "yd-popup-warn"
      }
      if (popupItem.type == "error") {
        popupItem.icon = require("./images/error.png")
        popupItem.closeIcon = require("./images/errorCloseIcon.png")
        popupItem.typeClass = "yd-popup-error"
      }
      return popupItem
    },
    // 展示
    showEvent(popupItem = { type: "error", message: "请输入相关提示语" }) {
      // 直接传入字符串就给个error类型
      if (!popupItem || typeof popupItem === "string") {
        popupItem = {
          type: "error",
          message: popupItem,
          duration: 3000
        }
      } else {
        if (!popupItem.type) popupItem.type = "error"
        if (!popupItem.message) popupItem.message = "请输入相关提示语"
      }
      if (popupItem.message && popupItem.message.toString().length > 20) {
        console.warn(
          "为了更好的浏览效果,popup传入的文字数量最好不要超过20个字符,文字：" +
            popupItem.message
        )
      }
      popupItem.uuid = this.getUuidEvent()
      popupItem.animator = "yd-fade_down"
      let newPopupItem = this.initEvent(popupItem)
      this.popupsList.push(newPopupItem)
      if (newPopupItem.isClickShow) {
        newPopupItem.isClickShow = true
      } else {
        newPopupItem.isClickShow = false
        this.disappearEvent(newPopupItem.uuid, newPopupItem.duration)
      }
    },
    success(msg) {
      this.showEvent({ type: "success", message: msg })
    },
    error(msg) {
      this.showEvent({ type: "error", message: msg })
    },
    warn(msg) {
      this.showEvent({ type: "warn", message: msg })
    },
    info(msg) {
      this.showEvent({ type: "info", message: msg })
    },
    disappearEvent(uuid, duration = 3000) {
      this.fadeOutAnimatorEvent(uuid, duration).then((res) => {
        setTimeout(() => {
          for (let i = 0; i < this.popupsList.length; i++) {
            if (this.popupsList[i].uuid == res) {
              this.popupsList.splice(i, 1)
              this.$forceUpdate();
            }
          }
        }, 250)
      })
    },
    fadeOutAnimatorEvent(uuid, duration) {
      return new Promise((resolve) => {
        setTimeout(() => {
          for (let i = 0; i < this.popupsList.length; i++) {
            if (this.popupsList[i].uuid == uuid) {
              this.popupsList[i].animator = "yd-fade_top"
              resolve(uuid)
            }
          }
        }, duration)
      })
    },
    closeEvent(uuid) {
      this.removeElementEvent(uuid).then((res) => {
        setTimeout(() => {
          for (let i = 0; i < this.popupsList.length; i++) {
            if (this.popupsList[i].uuid == res) {
              this.popupsList.splice(i, 1)
              this.$emit("closeCallback", uuid)
              this.$forceUpdate()
            }
          }
        }, 250)
      })
    },
    removeElementEvent(uuid) {
      return new Promise((resolve) => {
        for (let i = 0; i < this.popupsList.length; i++) {
          if (this.popupsList[i].uuid == uuid) {
            this.popupsList[i].animator = "yd-fade_top"
            resolve(uuid)
            break
          }
        }
      })
    },
    getUuidEvent() {
      return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(
        /[xy]/g,
        function (c) {
          var r = (Math.random() * 16) | 0,
            v = c == "x" ? r : (r & 0x3) | 0x8;
          return v.toString(16)
        }
      )
    }
  }
}
</script>

<style>
.yd-popup {
  width: 560rpx;
  min-height: 40px;
  position: fixed;
  top: 10rpx;
  left: 0;
  right: 0;
  z-index: 5000;
  box-sizing: border-box;
  margin: 0 auto;
  border-radius: 5px;
  white-space: nowrap;
  padding: 8rpx 20rpx 8rpx 12rpx;
  background: #007aff;
  transition: all 0.5s;
}
.yd-popup .yd-popup-icon {
  width: 56rpx;
  min-width: 56rpx;
  height: 56rpx;
}
.yd-popup .yd-popup-text {
  font-size: 28rpx;
  flex: 1;
  white-space: pre-wrap;
}
.yd-popup-info {
  background: rgba(156, 212, 255, 0.72);
  border: 1px solid #9cd4ff;
  color: #ffffff;
}
.yd-popup-success {
  background: rgba(13, 206, 127, 0.72);
  border: 1px solid #0dce7f;
  color: #ffffff;
}
.yd-popup-warn {
  background: rgba(254, 132, 86, 0.72);
  border: 1px solid #fe8456;
  color: #ffffff;
}
.yd-popup-error {
  background: rgba(255, 68, 68, 0.72);
  border: 1px solid #ff4444;
  color: #ffffff;
}
.yd-fade_down {
  animation: fadeInDown 0.6s both;
}
.yd-fade_top {
  animation: fadeInTop 0.5s forwards;
}
.yd-top-0 {
  top: 0 !important;
}
@keyframes fadeInDown {
  from {
    opacity: 0;
    -webkit-transform: translate(0, -100px);
    transform: stranslate(0, -100px);
  }
  to {
    opacity: 1;
    -webkit-transform: translate(0, 10px);
    transform: stranslate(0, 10px);
  }
}
@keyframes fadeInTop {
  from {
    opacity: 1;
    -webkit-transform: translate(0, 10px);
    transform: stranslate(0, 10px);
  }
  to {
    opacity: 0;
    -webkit-transform: translate(0, -100px);
    transform: stranslate(0, -100px);
  }
}
</style>
